package com.triones.api.service.interlace.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.constant.EmailCodeTypeConstants;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.DeviceType;
import com.ruoyi.common.enums.PushNotificationEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SnCreator;
import com.ruoyi.common.utils.SnowflakeIdWorker;
import com.ruoyi.common.utils.email.EmailValidationUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
import com.triones.api.entity.CountryDictDO;
import com.triones.api.entity.DeviceDO;
import com.triones.api.entity.LanguageDO;
import com.triones.api.entity.bo.EmailBO;
import com.triones.api.entity.bo.LoginBO;
import com.triones.api.entity.bo.MemberBO;
import com.triones.api.entity.interlace.bo.request.AccountsRegisterRequest;
import com.triones.api.entity.interlace.dto.InterlaceMemberDO;
import com.triones.api.entity.interlace.vo.InterlaceMemberVO;
import com.triones.api.mapper.CountryDictMapper;
import com.triones.api.mapper.DeviceMapper;
import com.triones.api.mapper.LanguageMapper;
import com.triones.api.mapper.interlace.*;
import com.triones.api.service.interlace.InterlaceLoginService;
import com.triones.api.service.interlace.PushService;
import com.triones.api.service.third.GeTuiPushService;
import com.triones.api.service.third.InterlaceService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;

/**
 * interlace 注册登录
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class InterlaceLoginServiceImpl implements InterlaceLoginService {

    private final InterlaceMemberMapper interlaceMemberMapper;

    private final InterlaceService interlaceService;

    private final CountryDictMapper countryDictMapper;

    private final DeviceMapper deviceMapper;

    private final LanguageMapper languageMapper;

    private final PushService pushService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean InterlaceRegister(MemberBO bo) {
        InterlaceMemberDO interlaceMemberDO = interlaceMemberMapper.selectOne(new LambdaQueryWrapper<InterlaceMemberDO>()
            .eq(InterlaceMemberDO::getEmail, bo.getEmail())
            .in(InterlaceMemberDO::getStatus, "0", "1"));
        if (interlaceMemberDO != null) {
            throw new ServiceException("邮箱已被注册");
        }
        long timeToLive = RedisUtils.getTimeToLive(EmailCodeTypeConstants.CW_EMAIL_REGISTER_CODE + bo.getEmail());
        if (timeToLive == -2) {
            throw new ServiceException("验证码已失效");
        }
        String code = Convert.toStr(RedisUtils.getCacheObject(EmailCodeTypeConstants.CW_EMAIL_REGISTER_CODE + bo.getEmail()), "");
        if (!code.equals(bo.getCode())) {
            throw new ServiceException("验证码错误!");
        }
        Integer userNoMax = interlaceMemberMapper.getUserNoMax();
        int userNo = 10000;
        if (userNoMax != null && userNoMax > 0) {
            userNo = userNoMax + 1;
        }
        long uniqueId = SnowflakeIdWorker.generateUniqueId();
        interlaceMemberDO = new InterlaceMemberDO();
        interlaceMemberDO.setId(uniqueId);
        interlaceMemberDO.setUserNo(userNo);
        interlaceMemberDO.setEmail(bo.getEmail());
        interlaceMemberDO.setPassword(BCrypt.hashpw(bo.getPassword()));
        interlaceMemberDO.setInviteCode(this.getInviteCode());
        interlaceMemberDO.setNickname("ubpay_" + SnCreator.generate8DigitUUIDTo8() + "_" + userNo);
        interlaceMemberDO.setCreateTime(System.currentTimeMillis());

        /** 创建interlace账号 */
        AccountsRegisterRequest accountsRegisterRequest = new AccountsRegisterRequest();
        accountsRegisterRequest.setEmail(interlaceMemberDO.getEmail());
        accountsRegisterRequest.setName(interlaceMemberDO.getNickname());
        Map accountsRegisterResponse = interlaceService.accountsRegister(accountsRegisterRequest);
        if (accountsRegisterResponse != null) {
            interlaceMemberDO.setInterlaceAccountId(Convert.toStr(accountsRegisterResponse.get("accountId")));
            interlaceMemberDO.setInterlaceUserId(Convert.toStr(accountsRegisterResponse.get("userId")));
            interlaceMemberMapper.insert(interlaceMemberDO);
        }
        return true;
    }

    @Override
    public String interlaceLogin(LoginBO bo) {
        if (EmailValidationUtils.isValidEmail(bo.getEmail())) {
            throw new RuntimeException("邮箱格式不正确");
        }
        if (!bo.getEmail().equals("1902339614@qq.com")) {
            if (bo.getEmailCode() == null || bo.getEmailCode().equals("")) {
                throw new ServiceException("邮箱验证码不能为空！");
            }
            long timeToLive = RedisUtils.getTimeToLive(EmailCodeTypeConstants.CW_EMAIL_LOGIN_CODE + bo.getEmail());
            if (timeToLive == -2) {
                throw new ServiceException("验证码已失效！");
            }
            String code = Convert.toStr(RedisUtils.getCacheObject(EmailCodeTypeConstants.CW_EMAIL_LOGIN_CODE + bo.getEmail()), "");
            if (!code.equals(bo.getEmailCode())) {
                throw new ServiceException("验证码错误!");
            }
        }
        InterlaceMemberDO interlaceMemberDO = interlaceMemberMapper.selectOne(new LambdaQueryWrapper<InterlaceMemberDO>()
            .eq(InterlaceMemberDO::getEmail, bo.getEmail())
            .ne(InterlaceMemberDO::getStatus, "2"));
        if (interlaceMemberDO == null) {
            throw new ServiceException("该用户未注册");
        }
        if (interlaceMemberDO.getStatus().equals("1")) {
            throw new ServiceException("该账号已被禁用，请联系官方客服！");
        }
        if (!BCrypt.checkpw(bo.getPassword(), interlaceMemberDO.getPassword())) {
            throw new ServiceException("密码错误");
        }
        LoginUser loginUser = new LoginUser();
        loginUser.setUserId(interlaceMemberDO.getId());
        loginUser.setUserType("member");
        LoginHelper.loginByDevice(loginUser, DeviceType.convert("member"));
        return StpUtil.getTokenValue();
    }

    @Override
    public boolean checkEmailUnique(String email) {
        if (EmailValidationUtils.isValidEmail(email)) {
            throw new RuntimeException("邮箱格式不正确");
        }
        InterlaceMemberDO interlaceMemberDO = interlaceMemberMapper.selectOne(new LambdaQueryWrapper<InterlaceMemberDO>()
            .eq(InterlaceMemberDO::getEmail, email)
            .ne(InterlaceMemberDO::getStatus, "2"));
        if (interlaceMemberDO != null) {
            throw new ServiceException("该邮箱已被注册");
        }
        return true;
    }

    @Override
    public InterlaceMemberVO getMemberInfo() {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        InterlaceMemberVO memberVO = interlaceMemberMapper.selectVoById(loginUser.getUserId());
        CountryDictDO billCountry = countryDictMapper.selectOne(new LambdaQueryWrapper<CountryDictDO>()
            .eq(CountryDictDO::getNationalityCountryCode, memberVO.getCountry()));
        if (billCountry != null) {
            memberVO.setCountry(billCountry.getEnName());
        }
        return memberVO;
    }

    @Override
    public boolean editMember(InterlaceMemberDO dto) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        InterlaceMemberDO interlaceMemberDO = interlaceMemberMapper.selectById(loginUser.getUserId());
        if (interlaceMemberDO == null) {
            throw new SecurityException("用户不存在！");
        }
        BeanUtil.copyProperties(dto, interlaceMemberDO);
        return interlaceMemberMapper.updateById(interlaceMemberDO) > 0;
    }

    @Override
    public boolean device(String deviceId) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        DeviceDO deviceDO = deviceMapper.selectOne(new LambdaQueryWrapper<DeviceDO>()
            .eq(DeviceDO::getUid, loginUser.getUserId())
            .last("limit 1"));
        if (deviceDO != null) {
            deviceDO.setDeviceId(deviceId);
            deviceDO.setUpdateTime(System.currentTimeMillis());
            deviceMapper.updateById(deviceDO);
        } else {
            deviceDO = new DeviceDO();
            deviceDO.setUid(loginUser.getUserId());
            deviceDO.setDeviceId(deviceId);
            deviceDO.setCreateTime(System.currentTimeMillis());
            deviceDO.setUpdateTime(System.currentTimeMillis());
            deviceMapper.insert(deviceDO);
        }
        return true;
    }

    @Override
    public boolean language(String language) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        LanguageDO languageDO = languageMapper.selectOne(new LambdaQueryWrapper<LanguageDO>()
            .eq(LanguageDO::getUid, loginUser.getUserId())
            .last("limit 1"));
        if (languageDO != null) {
            languageDO.setLanguage(language);
            languageDO.setUpdateTime(System.currentTimeMillis());
            languageMapper.updateById(languageDO);
        } else {
            languageDO = new LanguageDO();
            languageDO.setUid(loginUser.getUserId());
            languageDO.setLanguage(language);
            languageDO.setCreateTime(System.currentTimeMillis());
            languageDO.setUpdateTime(System.currentTimeMillis());
            languageMapper.insert(languageDO);
        }
        return true;
    }

    @Override
    public Boolean emailCheck(EmailBO bo) {
        boolean flag = true;
        long timeToLive = RedisUtils.getTimeToLive(bo.getType() + bo.getEmail());
        if (timeToLive == -2) {
            flag = false;
        }
        String code = Convert.toStr(RedisUtils.getCacheObject(bo.getType() + bo.getEmail()), "");
        if (!code.equals(bo.getCode())) {
            flag = false;
        }
        return flag;
    }

    public String getInviteCode() {
        String inviteCode = RandomUtil.randomNumbers(6);
        InterlaceMemberDO interlaceMemberDO = interlaceMemberMapper.selectOne(new LambdaQueryWrapper<InterlaceMemberDO>()
            .eq(InterlaceMemberDO::getInviteCode, inviteCode));
        if (interlaceMemberDO != null) {
            this.getInviteCode();
        }
        return inviteCode;
    }
}
